/**
 * 创建一个简单的事件总线，用于在Vue 3中实现组件间通信
 * 代替Vue 2中的$on, $off和$emit方法
 */

type EventHandler = (...args: any[]) => void;

interface Events {
  [key: string]: EventHandler[];
}

class EventBus {
  private events: Events = {};

  /**
   * 注册事件监听器
   * @param event 事件名称
   * @param callback 回调函数
   */
  on(event: string, callback: EventHandler): void {
    if (!this.events[event]) {
      this.events[event] = [];
    }
    this.events[event].push(callback);
  }

  /**
   * 移除事件监听器
   * @param event 事件名称
   * @param callback 可选的回调函数，如果不提供则移除该事件的所有监听器
   */
  off(event: string, callback?: EventHandler): void {
    if (!this.events[event]) return;

    if (!callback) {
      // 移除该事件的所有监听器
      delete this.events[event];
      return;
    }

    // 移除特定的回调函数
    this.events[event] = this.events[event].filter(cb => cb !== callback);
  }

  /**
   * 触发事件
   * @param event 事件名称
   * @param args 传递给事件处理函数的参数
   */
  emit(event: string, ...args: any[]): void {
    if (!this.events[event]) return;

    this.events[event].forEach(callback => {
      callback(...args);
    });
  }

  /**
   * 只监听事件一次，触发后自动移除
   * @param event 事件名称
   * @param callback 回调函数
   */
  once(event: string, callback: EventHandler): void {
    const wrapper = (...args: any[]) => {
      callback(...args);
      this.off(event, wrapper);
    };
    this.on(event, wrapper);
  }
}

// 创建一个全局事件总线实例
export const eventBus = new EventBus();

// 为了兼容旧代码，可以将事件总线挂载到window对象上
// 在生产环境中应该避免污染全局命名空间
if (typeof window !== 'undefined') {
  (window as any).eventBus = eventBus;
}

export default eventBus; 